﻿// ***********************************************************************
// Assembly         : Invisionware.API.Amazon
// Author           : Shawn Anderson (sanderson@eye-catcher.com)
// Created          : 01-10-2014
//
// Last Modified By : Shawn Anderson
// Last Modified On : 01-19-2014
// ***********************************************************************
// <copyright file="ItemDataTypes.cs" company="Invisionware">
//     Copyright (c) Invisionware. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************

using System;
using System.Collections.Generic;

namespace Invisionware.API.Amazon
{

	/// <summary>
	/// Class AwsItemSearchOptions.
	/// </summary>
	public class AwsItemSearchOptions
	{
		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="AwsItemSearchOptions"/> class.
		/// </summary>
		public AwsItemSearchOptions()
		{
			ResponseGroup = AwsItemResponseGroupTypes.Small;
			Availability = "Available";
			Condition = AwsItemCoditionTypes.New;
			IncludeReviewsSummary = true;
		}
		#endregion Constructors

		#region Public Properties
		/// <summary>
		/// Name of an actor associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The actor.</value>
		public string Actor { get; set; }

		/// <summary>
		/// Name of an artist associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The artist.</value>
		public string Artist { get; set; }

		/// <summary>
		/// Movie ratings based on MPAA ratings or age, depending upon the locale. You may specify one or
		/// more values in a comma-separated list in a REST request or by using multiple elements in a SOAP request.
		/// Type: String.
		/// Type: String
		/// Default: None
		/// Required: No
		/// Valid Values: See Movie Ratings by Locale, which follows this table.
		/// Locale	AudienceRating Values
		/// CA 		G, PG, PG-13, R, NC-17, NR, Unrated, Family Viewing
		/// DE 		6, 12, 16
		/// FR 		PG, 12, 16, 18
		/// US 		G, PG, PG-13, R, NC-17, NR, Unrated
		/// Required: No
		/// </summary>
		/// <value>The audience rating.</value>
		public string AudienceRating { get; set; }

		/// <summary>
		/// Name of an author associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The author.</value>
		public string Author { get; set; }

		/// <summary>
		/// Enables ItemSearch to return only those items that are available. This parameter must be used in
		/// combination with a merchant ID and Condition. For more information, see Availability Parameter,
		/// which follows this table.When Availability is set to "Available," the Condition parameter cannot be set to "New."
		/// Type: String
		/// Default: None
		/// Valid Values: Available
		/// Required: Yes
		/// </summary>
		/// <value>The availability.</value>
		public string Availability { get; private set; }

		/// <summary>
		/// Name of a brand associated with the item. You can enter all or part of the name.
		/// Type: String, for example, Timex, Seiko, Rolex.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The brand.</value>
		public string Brand { get; set; }

		/// <summary>
		/// Gets or sets the browse node.
		/// </summary>
		/// <value>The browse node.</value>
		public uint? BrowseNode { get; set; }

		/// <summary>
		/// Name of an composer associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The composer.</value>
		public string Composer { get; set; }

		/// <summary>
		/// Use the Condition parameter to filter the offers returned in the product list by condition type.
		/// By default, Condition equals "New". If you do not get results, consider changing the value to "All".
		/// When the Availability parameter is set to "Available," the Condition parameter cannot be set to "New."
		/// ItemSearch returns up to ten search results at a time. When condition equals "All," ItemSearch returns
		/// up to three offers per condition (if they exist), for example, three new, three used, three refurbished,
		/// and three collectible items. Or, for example, if there are no collectible or refurbished offers, ItemSearch
		/// returns three new and three used offers.
		/// Type: String
		/// Default: New
		/// Valid Values: Used | Collectible | Refurbished | All
		/// Required: No
		/// </summary>
		/// <value>The condition.</value>
		public AwsItemCoditionTypes? Condition { get; set; }

		/// <summary>
		/// Name of a conductor associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The conductor.</value>
		public string Conductor { get; set; }

		/// <summary>
		/// Name of a director associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The director.</value>
		public string Director { get; set; }

		/// <summary>
		/// When set to true, returns the reviews summary within the Reviews iframe.
		/// Type: Boolean
		/// Default: True
		/// Valid Values: True | False
		/// Required: No
		/// </summary>
		/// <value>The include reviews summary.</value>
		public bool? IncludeReviewsSummary { get; set; }

		/// <summary>
		/// Retrieves a specific page of items from all of the items in a response. Up to ten items are returned
		/// on a page unless Condition equals "All." In that case, ItemSearch returns additional offers for those
		/// items, one offer per condition type (if an offer exists)—for example, one new, one used, one refurbished,
		/// and one collectible item. Or, for example, if there are no collectible or refurbished offers, ItemSearch
		/// returns one new and one used offer. If you do not include ItemPage in your request, the first page is
		/// returned. The total number of pages of items found is returned in the TotalPages response tag.
		/// Valid Values: 1 to 10 (1 to 5 when the search index = "All")
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The item page.</value>
		public uint? ItemPage { get; set; }

		/// <summary>
		/// A word or phrase associated with an item. The word or phrase can be in various product fields, including
		/// product title, author, artist, description, manufacturer, and so forth. When, for example, the search
		/// index equals "MusicTracks," the Keywords parameter enables you to search by song title. If you enter a
		/// phrase, the spaces must be URL-encoded as %20.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The keywords.</value>
		public string Keywords { get; set; }

		/// <summary>
		/// Name of a manufacturer associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The manufacturer.</value>
		public string Manufacturer { get; set; }

		/// <summary>
		/// Specifies the maximum price of the items in the response. Prices are in terms of the lowest currency
		/// denomination, for example, pennies. For example, 3241 represents $32.41.
		/// Type: String
		/// Default: None
		/// Valid Values: Positive integer
		/// Required: No
		/// </summary>
		/// <value>The maximum price.</value>
		public uint? MaximumPrice { get; set; }

		/// <summary>
		/// An optional parameter you can use to filter search results and offer listings to only include items
		/// sold by Amazon. By default, Product Advertising API returns items sold by various merchants including
		/// Amazon. Use the Amazon to limit the response to only items sold by Amazon.
		/// Type: String
		/// Valid Values: Amazon
		/// Required: No
		/// </summary>
		/// <value>The merchant identifier.</value>
		public string MerchantId { get; set; }

		/// <summary>
		/// Specifies the minimum price of the items to return. Prices are in terms of the lowest currency
		/// denomination, for example, pennies, for example, 3241 represents $32.41.
		/// Type: String
		/// Default: None
		/// Valid Values: Positive integer
		/// Required: No
		/// </summary>
		/// <value>The minimum price.</value>
		public uint? MinimumPrice { get; set; }

		/// <summary>
		/// Specifies the minimum percentage off for the items to return.
		/// Type: String
		/// Default: None
		/// Valid Values: Positive integer
		/// Required: No
		/// </summary>
		/// <value>The minimum percentage off.</value>
		public uint? MinPercentageOff { get; set; }

		/// <summary>
		/// Name of an orchestra associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The orchestra.</value>
		public string Orchestra { get; set; }

		/// <summary>
		/// Performs a book search using a complex query string. Only works when the search index is set equal to "Books."
		/// Valid Values: See, Power Searches following this table.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The power.</value>
		public string Power { get; set; }

		/// <summary>
		/// Name of a publisher associated with the item. You can enter all or part of the name.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The publisher.</value>
		public string Publisher { get; set; }

		/// <summary>
		/// This optional parameter is only valid when the RelatedItems response group is used. Each ItemLookup
		/// request can return, at most, ten related items. The RelatedItemPage value specifies the set of ten
		/// related items to return. A value of 2, for example, returns the second set of ten related items.
		/// Required: No
		/// </summary>
		/// <value>The related item page.</value>
		public string RelatedItemPage { get; set; }

		/// <summary>
		/// This parameter is required when the RelatedItems response group is used. The type of related item
		/// returned is specified by the RelationshipType parameter. Sample values include Episode, Season, and
		/// Tracks. A complete list of values follows this table.
		/// Constraint: Required when RelatedItems response group is used
		/// Required: Conditional
		/// </summary>
		/// <value>The type of the relationship.</value>
		public string RelationshipType { get; set; }

		/// <summary>
		/// The product category to search. Many ItemSearch parameters are valid with only specific values of SearchIndex.
		/// Type: String
		/// Default: None
		/// Valid Values: A search index, for example, Apparel, Beauty, Blended, Books, and so forth. For Blended
		/// searches, go to Blended Searches. For a complete list of search indices, see Search Indices by Locale.
		/// Required: Yes
		/// </summary>
		/// <value>The index of the search.</value>
		public string SearchIndex { get; set; }

		/// <summary>
		/// Means by which the items in the response are ordered.
		/// Type: String
		/// Default: None
		/// Valid Values: Valid values vary significantly by search index. For a list of valid values, see
		/// ItemSearch Sort Values by Locale. http://docs.aws.amazon.com/AWSECommerceService/2011-08-01/DG/USSortValuesArticle.html
		/// Required: No
		/// </summary>
		/// <value>The sort.</value>
		public string Sort { get; set; }

		/// <summary>
		/// The title associated with the item. You can enter all or part of the title. Title searches are a
		/// subset of Keyword searches. If a Title search yields insufficient results, consider using a Keywords search.
		/// Type: String
		/// Default: None
		/// Required: No
		/// </summary>
		/// <value>The title.</value>
		public string Title { get; set; }

		/// <summary>
		/// By default, reviews are truncated to 1000 characters within the Reviews iframe. To specify a different
		/// length, enter the value. To return complete reviews, specify 0.
		/// Type: Integer
		/// Default: 1000
		/// Constraints: Must be a positive integer or 0 (returns entire review)
		/// Required: No
		/// </summary>
		/// <value>The truncate reviews at.</value>
		public uint? TruncateReviewsAt { get; set; }

		/// <summary>
		/// Retrieves a specific page of variations returned by ItemSearch. By default, ItemSearch returns all
		/// variations. Use VariationPage to return a subsection of the response. There are 10 variations per page.
		/// To examine offers 11 trough 20, for example, set VariationPage to 2. The total number of pages is returned
		/// in the TotalPages element.
		/// Type: String
		/// Default: None
		/// Valid Values: Positive integer
		/// Required: No
		/// </summary>
		/// <value>The variation page.</value>
		public uint? VariationPage { get; set; }

		/// <summary>
		/// Specifies the types of values to return. You can specify multiple response groups in one request by
		/// separating them with commas.
		/// Type: String
		/// Default: Small
		/// Valid Values: Accessories | BrowseNodes | EditorialReview | ItemAttributes | ItemIds | Large | Medium |
		/// OfferFull | Offers | OfferSummary | Reviews | RelatedItems | SearchBins | Similarities | Small | Tracks |
		/// Variations | VariationSummary
		/// Required: No
		/// </summary>
		/// <value>The response group.</value>
		public AwsItemResponseGroupTypes? ResponseGroup { get; set; }
		#endregion Public Properties

		#region Internal Methods
		/// <summary>
		/// Prepares this instance.
		/// </summary>
		/// <returns>IDictionary{System.StringSystem.String}.</returns>
		internal IDictionary<string, string> Prepare()
		{
			var r1 = new Dictionary<string, string>();

			if (!string.IsNullOrEmpty(Actor)) r1["Actor"] = Actor;
			if (!string.IsNullOrEmpty(Artist)) r1["Artist"] = Artist;
			if (!string.IsNullOrEmpty(AudienceRating)) r1["AudienceRating"] = AudienceRating;
			if (!string.IsNullOrEmpty(Author)) r1["Author"] = Author;
			if (!string.IsNullOrEmpty(Availability)) r1["Availability"] = Availability;
			if (!string.IsNullOrEmpty(Brand)) r1["Brand"] = Brand;
			if (BrowseNode.HasValue) r1["BrowseNode"] = BrowseNode.Value.ToString();
			if (!string.IsNullOrEmpty(Composer)) r1["Composer"] = Composer;
			if (Condition.HasValue) r1["Condition"] = Condition.Value.ToString();
			if (!string.IsNullOrEmpty(Conductor)) r1["Conductor"] = Conductor;
			if (!string.IsNullOrEmpty(Director)) r1["Director"] = Director;
			if (IncludeReviewsSummary.HasValue) r1["IncludeReviewsSummar"] = IncludeReviewsSummary.Value.ToString();
			if (ItemPage.HasValue) r1["ItemPage"] = ItemPage.Value.ToString();
			if (!string.IsNullOrEmpty(Keywords)) r1["Keywords"] = Keywords;
			if (!string.IsNullOrEmpty(Manufacturer)) r1["Manufacturer"] = Manufacturer;
			if (MaximumPrice.HasValue) r1["MaximumPrice"] = MaximumPrice.Value.ToString();
			if (!string.IsNullOrEmpty(MerchantId)) r1["MerchantId"] = MerchantId;
			if (MinimumPrice.HasValue) r1["MinimumPrice"] = MinimumPrice.Value.ToString();
			if (MinPercentageOff.HasValue) r1["MinPercentageOff"] = MinPercentageOff.Value.ToString();
			if (!string.IsNullOrEmpty(Orchestra)) r1["Orchestra"] = Orchestra;
			if (!string.IsNullOrEmpty(Power)) r1["Power"] = Power;
			if (!string.IsNullOrEmpty(Publisher)) r1["Publisher"] = Publisher;
			if (!string.IsNullOrEmpty(RelatedItemPage)) r1["RelatedItemPage"] = RelatedItemPage;
			if (!string.IsNullOrEmpty(RelationshipType)) r1["RelationshipType"] = RelationshipType;
			if (!string.IsNullOrEmpty(SearchIndex)) r1["SearchIndex"] = SearchIndex;
			if (!string.IsNullOrEmpty(Sort)) r1["Sort"] = Sort;
			if (!string.IsNullOrEmpty(Title)) r1["Title"] = Title;
			if (TruncateReviewsAt.HasValue) r1["TruncateReviewsAt"] = TruncateReviewsAt.Value.ToString();
			if (VariationPage.HasValue) r1["VariationPage"] = VariationPage.Value.ToString();
			if (ResponseGroup.HasValue) r1["ResponseGroup"] = ResponseGroup.Value.ToString();

			if (r1.Count == 0) throw new InvalidOperationException("No Search Options Specified");

			return r1;
		}
		#endregion Internal Methods
	}
}
